﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ShortcutsEditorForm.cs" company="TechBits">
//   Copyright (c) TechBits. All rights reserved.
// </copyright>
// <author>
//   Leandro G. Vacirca.
// </author>
// <summary>
//   Defines the ShortcutsEditorForm type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace IntelliShortCut.UI.Forms
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Linq;    
    using System.Windows.Forms;
    
    using Application;
    using Application.Helpers;
    using Data;
    using Helpers;
    using Properties;

    /// <summary>
    /// The shortcuts editor form.
    /// </summary>
    public partial class ShortcutsEditorForm : InfoBaseForm
    {
        #region "Constants"

        /// <summary>
        /// The background color of the invalid shortcuts cells.
        /// </summary>
        private static readonly Color INVALID_BACKCOLOR = Color.LightCoral;

        /// <summary>
        /// The background color of the invalid shortcuts cells when they are selected.
        /// </summary>
        private static readonly Color INVALID_SELBACKCOLOR = Color.IndianRed;

        /// <summary>
        /// The background color of the files shortcuts cells.
        /// </summary>
        private static readonly Color FILES_BACKCOLOR = Color.Azure;

        /// <summary>
        /// The background color of the files shortcuts cells when they are selected.
        /// </summary>
        private static readonly Color FILES_SELBACKCOLOR = Color.LightCyan;

        /// <summary>
        /// The background color of the folders shortcuts cells.
        /// </summary>
        private static readonly Color FOLDERS_BACKCOLOR = Color.Cornsilk;

        /// <summary>
        /// The background color of the folders shortcuts cells when they are selected.
        /// </summary>
        private static readonly Color FOLDERS_SELBACKCOLOR = Color.LemonChiffon;

        #endregion

        #region "Private Members"

        /// <summary>
        /// Indicates the mode of the saves button. True: adds shortctus; False: updates shortcuts.
        /// </summary>
        private bool _saveMode;

        #endregion

        #region "Constructors"

        /// <summary>
        /// Initializes a new instance of the <see cref="ShortcutsEditorForm"/> class. 
        /// </summary>
        public ShortcutsEditorForm()
        {
            InitializeComponent();
        }

        #endregion

        #region "Public Members"

        /// <summary>
        /// Gets WindowTittle.
        /// </summary>
        public static string WindowTittle
        {
            get
            {
                return "Shortcuts Editor";
            }
        }

        #endregion

        #region "UI Events"

        /// <summary>
        /// Form load event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsEditorForm_Load(object sender, EventArgs e)
        {
            LoadData();
        }

        /// <summary>
        /// Adds to the datagridview the application on the ProgramFiles folder.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void SearchToolStripButton_Click(object sender, EventArgs e)
        {            
            Cursor = Cursors.WaitCursor;
            ShortcutsDataGridView.Cursor = Cursors.WaitCursor;
            StatusLabel.Text = "Searching installed applications...";

            SearchBackgroundWorker.RunWorkerAsync();
        }

        /// <summary>
        /// Saves the changes.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void SaveToolStripButton_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            StatusLabel.Text = "Saving changes...";

            try
            {
                Application.DoEvents();                                
                SaveChanges();
                SaveToolStripButton.Enabled = false;
                _saveMode = false;
            }
            finally
            {
                Cursor = Cursors.Default;
                StatusLabel.Text = "Changes have been saved.";
            }            
        }

        /// <summary>
        /// Solve conflicts due invalid shortcuts.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The eevent parameters.</param>
        private void SolveConflictToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog.Description = "Select the updated path of the shortcut...";
            FolderBrowserDialog.ShowNewFolderButton = true;

            var result = FolderBrowserDialog.ShowDialog();
            if (result == DialogResult.OK)
            {
                var messageResult =
                    MessageBox.Show(
                        string.Format("Are you sure to update the shortcut path to {0} ?", FolderBrowserDialog.SelectedPath),
                        "Solve conflicts",
                        MessageBoxButtons.YesNo,
                        MessageBoxIcon.Question,
                        MessageBoxDefaultButton.Button2);

                if (messageResult == DialogResult.Yes)
                {
                    if (ShortcutDataBindingSource.AllowEdit)
                    {
                        var selectedRow = (ShortcutData) ShortcutsDataGridView.SelectedRows[0].DataBoundItem;
                        selectedRow.Valid = true;
                        selectedRow.FullPath = Path.HasExtension(selectedRow.FullPath) ? Path.Combine(FolderBrowserDialog.SelectedPath, Path.GetFileName(selectedRow.FullPath)) : FolderBrowserDialog.SelectedPath;
                        
                        _saveMode = false;
                        SaveToolStripButton.Enabled = true;
                        ShortcutDataBindingSource.EndEdit();
                        ShortcutsDataGridView.Refresh();
                    }
                }
            }
        }

        /// <summary>
        /// Removes the selected shortcut.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void RemoveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _saveMode = false;
            SaveToolStripButton.Enabled = true;
            ShortcutApl.Instance.RemoveShortcut((ShortcutData)ShortcutsDataGridView.SelectedRows[0].DataBoundItem);
            LoadData();
        }

        /// <summary>
        /// Searches for installed application on a background worker thread.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void SearchBackgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            var result = SearchShortcuts().ToSortableList();
            e.Result = result;
        }

        /// <summary>
        /// Shows the results of the search.</summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void SearchBackgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            var result = e.Result;
            var currentItemsCount = ShortcutDataBindingSource.List.Count;

            try
            {
                ShortcutDataBindingSource.Clear();
                ShortcutDataBindingSource.DataSource = result;
                _saveMode = true;
            }
            finally
            {
                Cursor = Cursors.Default;
                ShortcutsDataGridView.Cursor = Cursors.Default;
                StatusLabel.Text = string.Format("{0} candidate shortcuts found.", ShortcutDataBindingSource.List.Count - currentItemsCount);
            }
        }

        /// <summary>
        /// Enables or disables the solve conflicts menu.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            var selectedRow = (ShortcutData)ShortcutsDataGridView.SelectedRows[0].DataBoundItem;

            SolveConflictToolStripMenuItem.Visible = !selectedRow.Valid;
            ToolStripSeparator1.Visible = !selectedRow.Valid;
        }

        /// <summary>
        /// Executes the selected shortcut.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsDataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (ShortcutsDataGridView.Columns[e.ColumnIndex].HeaderText.Equals(fullPathDataGridViewTextBoxColumn.HeaderText))
            {
                if (ShortcutsDataGridView.CurrentRow != null)
                {
                    var shortcut = (ShortcutData)ShortcutsDataGridView.Rows[ShortcutsDataGridView.CurrentRow.Index].DataBoundItem;

                    try
                    {
                        Process.Start(shortcut.FullPath);
                    }
                    catch
                    {                        
                    }
                }                
            }
        }

        /// <summary>
        /// Applies a row backcolor scheme depending on the state of the shortcut. 
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            var row = (ShortcutData)ShortcutsDataGridView.Rows[e.RowIndex].DataBoundItem;
            if (row == null)
            {
                return;
            }

            if (!row.Valid)
            {
                e.CellStyle.SelectionForeColor = Color.Black;
                e.CellStyle.BackColor = INVALID_BACKCOLOR;
                e.CellStyle.SelectionBackColor = INVALID_SELBACKCOLOR;
                return;
            }

            switch (row.Category)
            {
                case ShortcutCategoryEnum.Files:
                    e.CellStyle.SelectionForeColor = Color.Black;
                    e.CellStyle.BackColor = FILES_BACKCOLOR;
                    e.CellStyle.SelectionBackColor = FILES_SELBACKCOLOR;
                    break;
                case ShortcutCategoryEnum.Folders:
                    e.CellStyle.SelectionForeColor = Color.Black;
                    e.CellStyle.BackColor = FOLDERS_BACKCOLOR;
                    e.CellStyle.SelectionBackColor = FOLDERS_SELBACKCOLOR;
                    break;
            }           
        }

        /// <summary>
        /// Enables the save button.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsDataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            StatusLabel.Text = "Current entry is being edited. Press Enter to end edit mode.";
        }

        /// <summary>
        /// Enables the save button.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            SaveToolStripButton.Enabled = true;
            StatusLabel.Text = "Click on Save button to save the changes.";
        }

        /// <summary>
        /// Shows the shortcut info.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event parameters.</param>
        private void ShortcutsDataGridView_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            ShowShortcutDescription();
        }

        #endregion

        #region "Private Methods"

        /// <summary>
        /// Gets the shortcuts based on the installed applications on Windows.
        /// </summary>
        /// <returns>
        /// A list of shortcuts based on the installed applications on Windows.
        /// </returns>
        private static List<ShortcutData> SearchShortcuts()
        {
            var shortcutCandidates = ShortcutFinderHelper.Instance.GetCandidateShortcuts();
            var shortcuts = ShortcutApl.Instance.GetShortcuts();
            foreach (var shortcut in shortcutCandidates)
            {
                ShortcutData data = shortcut;
                if (shortcuts.SingleOrDefault(s => s.FullPath.Equals(data.FullPath)) == null)
                {
                    shortcuts.Add(shortcut);
                }
            }

            return shortcuts.ToList();
        }

        /// <summary>
        /// Loads the shortcuts data into the datagrid.
        /// </summary>
        private void LoadData()
        {
            ShortcutDataBindingSource.DataSource = ShortcutApl.Instance.GetShortcuts().ToSortableList();
        }

        /// <summary>
        /// Saves the changes.
        /// </summary>
        private void SaveChanges()
        {
            var data = new List<ShortcutData>();
            foreach (var shortcut in ShortcutDataBindingSource.List)
            {
                data.Add((ShortcutData)shortcut);
            }

            if (_saveMode)
            {
                foreach (var shortcutData in data)
                {
                    // Adds the active shortcuts
                    if (shortcutData.Active)
                    {
                        ShortcutApl.Instance.AddShortcut(shortcutData, true);
                    }
                }

                // Reloads the datagrid
                ShortcutDataBindingSource.Clear();
                ShortcutDataBindingSource.DataSource = ShortcutApl.Instance.GetShortcuts().ToSortableList();
            }
            else
            {
                ShortcutApl.Instance.UpdateShortcuts(data);
            }
        }

        /// <summary>
        /// Shows the shortcut info.
        /// </summary>
        private void ShowShortcutDescription()
        {
            if (ShortcutsDataGridView.CurrentRow != null)
            {
                var shortcutInfo = (ShortcutData)ShortcutsDataGridView.Rows[ShortcutsDataGridView.CurrentRow.Index].DataBoundItem;
                IconPictureBox.Image = shortcutInfo.Icon;
                ValidStatusPictureBox.Image = shortcutInfo.Valid ? Resources.ValidStatus : Resources.Exit;
                ActivePictureBox.Image = shortcutInfo.Active ? Resources.EnabledShortcut : Resources.DisabledShortcut;
                NameValueLabel.Text = shortcutInfo.ByNameOrAlias ? shortcutInfo.Name : shortcutInfo.Alias;
                CategoryValueLabel.Text = shortcutInfo.Category.ToString();
                RankValueLabel.Text = shortcutInfo.Rank.ToString();
                PathTextBox.Text = shortcutInfo.FullPath;
            }          
        }

        #endregion
    }
}